package presentation;

import businessEntities.ColumnsInformationContainer;
import businessEntities.BEFileUtils;
import businessEntities.FilesConfig;
import businessEntities.NodeData;
import businessEntities.QueryResultContainer;
import businessLogic.BLConnetionManager;
import businessLogic.BLFileExporter;
import businessLogic.BLQueryMenager;
import java.awt.Font;
import java.awt.Toolkit;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import javax.swing.ImageIcon;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;
import org.jdesktop.swingx.JXTree;
import presentation.entities.JFrameWrapper;
import presentation.entities.DialogCreator;
import presentation.entities.QueryTableModel;
import presentation.entities.TreeMouseListner;

public class TableFilteringScreen extends javax.swing.JFrame {

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        filterScreen_panel = new javax.swing.JPanel();
        tree_scrollPane = new javax.swing.JScrollPane();
        titles_panel = new javax.swing.JPanel();
        dbName_label = new javax.swing.JLabel();
        tableName_label = new javax.swing.JLabel();
        filter_scroll = new javax.swing.JScrollPane();
        filter_textField = new javax.swing.JTextField();
        menuBar = new javax.swing.JMenuBar();
        navigation_menu = new javax.swing.JMenu();
        back_menuItem = new javax.swing.JMenuItem();
        backPrev_menuItem = new javax.swing.JMenuItem();
        jSeparator1 = new javax.swing.JPopupMenu.Separator();
        close_menuItem = new javax.swing.JMenuItem();
        tools_menu = new javax.swing.JMenu();
        exportTree_menuItem = new javax.swing.JMenuItem();

        setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE);
        setTitle("Dynamical  SQL - Table Filtering");
        setIconImage(Toolkit.getDefaultToolkit().getImage(PresentationConfig.framesIconPath));
        setName("dbFilterScreen_frame"); // NOI18N
        setState(MAXIMIZED_BOTH);

        filterScreen_panel.setLayout(new java.awt.BorderLayout());

        tree_scrollPane.setBorder(null);
        filterScreen_panel.add(tree_scrollPane, java.awt.BorderLayout.CENTER);

        dbName_label.setFont(new java.awt.Font("Microsoft YaHei", 1, 20));
        dbName_label.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
        dbName_label.setText("TEMP");

        tableName_label.setFont(new java.awt.Font("Arial Rounded MT Bold", 1, 28));
        tableName_label.setForeground(new java.awt.Color(0, 0, 255));
        tableName_label.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
        tableName_label.setText("TEMP");

        filter_scroll.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER);

        filter_textField.setEditable(false);
        filter_textField.setFont(new java.awt.Font("Arial Rounded MT Bold", 0, 12));
        filter_textField.setFocusable(false);
        filter_scroll.setViewportView(filter_textField);

        org.jdesktop.layout.GroupLayout titles_panelLayout = new org.jdesktop.layout.GroupLayout(titles_panel);
        titles_panel.setLayout(titles_panelLayout);
        titles_panelLayout.setHorizontalGroup(
            titles_panelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(dbName_label, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 650, Short.MAX_VALUE)
            .add(tableName_label, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 650, Short.MAX_VALUE)
            .add(filter_scroll, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 650, Short.MAX_VALUE)
        );
        titles_panelLayout.setVerticalGroup(
            titles_panelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(titles_panelLayout.createSequentialGroup()
                .add(dbName_label, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 28, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(tableName_label, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 33, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(filter_scroll, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 47, Short.MAX_VALUE))
        );

        filterScreen_panel.add(titles_panel, java.awt.BorderLayout.PAGE_START);

        navigation_menu.setIcon(new javax.swing.ImageIcon(getClass().getResource("/icons/navigation-icon.png"))); // NOI18N
        navigation_menu.setText("Navigation");
        navigation_menu.setFont(new java.awt.Font("Arial Rounded MT Bold", 1, 12));

        back_menuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_A, java.awt.event.InputEvent.SHIFT_MASK));
        back_menuItem.setFont(new java.awt.Font("Arial Rounded MT Bold", 0, 12));
        back_menuItem.setIcon(new javax.swing.ImageIcon(getClass().getResource("/icons/database-connection-icon.png"))); // NOI18N
        back_menuItem.setText("Back to login screen");
        back_menuItem.setToolTipText("Disconnect  from the server and go back to login screen ");
        back_menuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                back_menuItemActionPerformed(evt);
            }
        });
        navigation_menu.add(back_menuItem);

        backPrev_menuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_B, java.awt.event.InputEvent.SHIFT_MASK));
        backPrev_menuItem.setFont(new java.awt.Font("Arial Rounded MT Bold", 0, 12));
        backPrev_menuItem.setIcon(new javax.swing.ImageIcon(getClass().getResource("/icons/database-list-24.png"))); // NOI18N
        backPrev_menuItem.setText("Back to previous screen");
        backPrev_menuItem.setToolTipText("Stay connect to the server and go back to previous screen.");
        backPrev_menuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                backPrev_menuItemActionPerformed(evt);
            }
        });
        navigation_menu.add(backPrev_menuItem);
        navigation_menu.add(jSeparator1);

        close_menuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_C, java.awt.event.InputEvent.SHIFT_MASK));
        close_menuItem.setFont(new java.awt.Font("Arial Rounded MT Bold", 0, 12));
        close_menuItem.setIcon(new javax.swing.ImageIcon(getClass().getResource("/icons/shutdown-icon.png"))); // NOI18N
        close_menuItem.setText("Close");
        close_menuItem.setToolTipText("Disconnect from the server and close the program");
        close_menuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                close_menuItemActionPerformed(evt);
            }
        });
        navigation_menu.add(close_menuItem);

        menuBar.add(navigation_menu);

        tools_menu.setIcon(new javax.swing.ImageIcon(getClass().getResource("/icons/tools-icon.png"))); // NOI18N
        tools_menu.setText("Tools");
        tools_menu.setFont(new java.awt.Font("Arial Rounded MT Bold", 1, 12));

        exportTree_menuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_E, java.awt.event.InputEvent.SHIFT_MASK));
        exportTree_menuItem.setFont(new java.awt.Font("Arial Rounded MT Bold", 0, 12)); // NOI18N
        exportTree_menuItem.setIcon(new javax.swing.ImageIcon(getClass().getResource("/icons/xml_icon.png"))); // NOI18N
        exportTree_menuItem.setText("Export Tree to XML");
        exportTree_menuItem.setToolTipText("Export the Current Tree to XML file");
        exportTree_menuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                exportTree_menuItemActionPerformed(evt);
            }
        });
        tools_menu.add(exportTree_menuItem);

        menuBar.add(tools_menu);

        setJMenuBar(menuBar);

        org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(org.jdesktop.layout.GroupLayout.TRAILING, filterScreen_panel, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 650, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(filterScreen_panel, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 400, Short.MAX_VALUE)
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

private void back_menuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_back_menuItemActionPerformed
    if (DialogCreator.backToLoginDialogSaveWarn(this) == 0) {
        setVisible(false);
        javax.swing.SwingUtilities.invokeLater(new Runnable() {

            public void run() {
                new ConnectionScreen().setVisible(true);
            }
        });
        closeConnectionOnClose = true;
        userClickOnExit = false;
        this.dispose();
    }
}//GEN-LAST:event_back_menuItemActionPerformed

private void close_menuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_close_menuItemActionPerformed
    if (DialogCreator.closeProgramDialogSaveWarn(this) == 0) {
        setVisible(false);
        closeConnectionOnClose = true;
        userClickOnExit = false;
        this.dispose();
    }
}//GEN-LAST:event_close_menuItemActionPerformed

    private void backPrev_menuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_backPrev_menuItemActionPerformed
        if (DialogCreator.backToListsScreenDialog(this) == 0) {
            setVisible(false);
            JFrame previousScreen = new ListsScreen();
            JFrameWrapper frameWrapper = new JFrameWrapper(previousScreen);
            javax.swing.SwingUtilities.invokeLater(frameWrapper);
            closeConnectionOnClose = false;
            userClickOnExit = false;
            this.dispose();
        }
    }//GEN-LAST:event_backPrev_menuItemActionPerformed

    private void exportTree_menuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_exportTree_menuItemActionPerformed
        
        File workspaceDir = new File(FilesConfig.WORKSPACE_DIR_PATH);
        JFileChooser fileChooser;
        if(workspaceDir.isDirectory()){
            fileChooser = new JFileChooser(workspaceDir);
        }
        else {
            fileChooser = new JFileChooser(System.getProperty("user.home"));
        }
        
        int returnVal = fileChooser.showSaveDialog(this);
        if (returnVal == JFileChooser.APPROVE_OPTION) {
            String fileName = fileChooser.getSelectedFile().getName();
            String ext = BEFileUtils.getFileExtention(fileName);
            File outputFile;
            if (ext.equals("xml")) {
                outputFile = new File(fileChooser.getSelectedFile().getAbsolutePath());
            } else {
                outputFile = new File(fileChooser.getSelectedFile() + ".xml");
            }
            if (outputFile.exists()) {
                int userResponse = DialogCreator.deleteExistFileDialog(this);
                if (userResponse != 0) {
                    return;
                }
            }
            BLFileExporter exporter = new BLFileExporter();
            boolean succeeded = exporter.saveTreeToFile(tree, outputFile);
            if (succeeded) {
                DialogCreator.showMessage(this, "Tree Export Completed", "Tree Export was completed successfully.", JOptionPane.INFORMATION_MESSAGE);
            } else {
                DialogCreator.showMessage(this, "Tree Export Failed", "Tree Export failed.\nInformation can be found in 'runtime.log' file.", JOptionPane.ERROR_MESSAGE);
            }
        }
    }//GEN-LAST:event_exportTree_menuItemActionPerformed

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JMenuItem backPrev_menuItem;
    private javax.swing.JMenuItem back_menuItem;
    private javax.swing.JMenuItem close_menuItem;
    private javax.swing.JLabel dbName_label;
    private javax.swing.JMenuItem exportTree_menuItem;
    private javax.swing.JPanel filterScreen_panel;
    private javax.swing.JScrollPane filter_scroll;
    private javax.swing.JTextField filter_textField;
    private javax.swing.JPopupMenu.Separator jSeparator1;
    private javax.swing.JMenuBar menuBar;
    private javax.swing.JMenu navigation_menu;
    private javax.swing.JLabel tableName_label;
    private javax.swing.JPanel titles_panel;
    private javax.swing.JMenu tools_menu;
    private javax.swing.JScrollPane tree_scrollPane;
    // End of variables declaration//GEN-END:variables
    private JXTree tree = null;
    private DefaultTreeModel treeModel = null;
    private ColumnsInformationContainer columnsDataConatiner = null;
    private String dataBaseName;
    private String tableName;
    private boolean userClickOnExit = true;
    private boolean closeConnectionOnClose = true;

    public TableFilteringScreen(String dataBaseName, String tableName, ColumnsInformationContainer columnsData, DefaultTreeModel treeModel) {

        this.dataBaseName = dataBaseName;
        this.tableName = tableName;
        this.columnsDataConatiner = columnsData;

        initComponents();

        initWindowListner();

        this.setLocationRelativeTo(null);
        this.setExtendedState(this.getExtendedState() | JFrame.MAXIMIZED_BOTH);

        dbName_label.setText("Database : " + dataBaseName);
        tableName_label.setText("Table : " + tableName);
        
        this.treeModel = treeModel;
        initTree();
    }

    private void initTree() {
        if(treeModel == null){
            NodeData rootData = NodeData.createRootNodeData(dataBaseName, tableName);
            DefaultMutableTreeNode root = new DefaultMutableTreeNode(rootData);
            treeModel = new DefaultTreeModel(root);
            treeModel.addTreeModelListener(null);
        }
        tree = new JXTree(treeModel);
        tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
        tree.setShowsRootHandles(true);
        tree.addMouseListener(new TreeMouseListner(this));
        tree.setFont(new Font("Microsoft YaHei", 1, 18));
        setTreeIcons();

        tree_scrollPane.setViewportView(tree);
    }

    private void setTreeIcons() {
        ImageIcon leafIcon = new ImageIcon(PresentationConfig.dbGearIconPath);
        ImageIcon closedIcon = new ImageIcon(PresentationConfig.dbPlusIconPath);

        if ((leafIcon != null) && (closedIcon != null)) {
            DefaultTreeCellRenderer renderer = new DefaultTreeCellRenderer();
            renderer.setLeafIcon(leafIcon);
            renderer.setOpenIcon(leafIcon);
            renderer.setClosedIcon(closedIcon);
            tree.setCellRenderer(renderer);
        }

    }

    public TreePath getLeadSelectedPath() {
        return tree.getLeadSelectionPath();
    }

    /**
     * @throws NullPointerException if <code>path == null</code> 
     */
    public void setFilterText(TreePath path) {
        if (path == null) {
            throw new NullPointerException("Path input parameter == null");
        }
        DefaultMutableTreeNode node = (DefaultMutableTreeNode) path.getLastPathComponent();
        NodeData nodeData = (NodeData) node.getUserObject();
        if (nodeData.isRootFilter()) {
            filter_textField.setText("SELECT * FROM (" + dataBaseName + "." + tableName + ")");
        } else {
            filter_textField.setText("SELECT * FROM (" + dataBaseName + "." + tableName + ") WHERE (" + nodeData.getWhereSentence() + ")");
        }
    }

    void showTable(TreePath path) {
        DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode) path.getLastPathComponent();
        NodeData nodeData = (NodeData) treeNode.getUserObject();

        BLQueryMenager dbQuery = new BLQueryMenager();
        QueryResultContainer dataContainer = dbQuery.getFilteredTable(nodeData);

        if (dataContainer == null) {
            String errorMessage = "An unexpected error occuered.\nCould not retrive information from the database !";
            DialogCreator.showMessage(this, "Database Connection Error", errorMessage, JOptionPane.ERROR_MESSAGE);
        } else {
            String tableFrameTitle;
            if (nodeData.isRootFilter()) {
                tableFrameTitle = "Database : " + dataBaseName + ", " + "Table : " + tableName;
            } else {
                tableFrameTitle = "Last Filter : " + nodeData;
            }

            QueryTableModel tableModel = new QueryTableModel(dataContainer);
            TableFrame tableFrame = new TableFrame(tableFrameTitle, tableModel);
            JFrameWrapper tableFrameWrapper = new JFrameWrapper(tableFrame);
            javax.swing.SwingUtilities.invokeLater(tableFrameWrapper);
        }
    }

    void addFilter(TreePath path) {

        DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode) path.getLastPathComponent();
        NodeData parentData = (NodeData) treeNode.getUserObject();

        String previousWhere;
        if (parentData.isRootFilter()) {
            previousWhere = "";
        } else {
            previousWhere = parentData.getPreviousFilters();
        }

        AddFilterDialog dialog = new AddFilterDialog(this, this.columnsDataConatiner, previousWhere);
        dialog.setVisible(true);
        String filter = dialog.getWhere();
        if (filter != null && !filter.equals("")) {
            DefaultMutableTreeNode newNode = new DefaultMutableTreeNode(new NodeData(filter, parentData));
            treeModel.insertNodeInto(newNode, treeNode, treeNode.getChildCount());
            tree.expandPath(tree.getLeadSelectionPath());
        }

    }

    void deleteFilter(TreePath path) {
        if(DialogCreator.deleteFilterDialog(this) != 0) return;
        DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode) path.getLastPathComponent();
        if (!treeNode.isRoot()) {
            treeModel.removeNodeFromParent(treeNode);
        }
    }

    void exportToCSV(TreePath path) {
        DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode) path.getLastPathComponent();
        NodeData selectedNodeData = (NodeData) treeNode.getUserObject();

        File workspaceDir = new File(FilesConfig.WORKSPACE_DIR_PATH);
        JFileChooser fileChooser;
        if(workspaceDir.isDirectory()){
            fileChooser = new JFileChooser(workspaceDir);
        }
        else {
            fileChooser = new JFileChooser(System.getProperty("user.home"));
        }
        
        int returnVal = fileChooser.showSaveDialog(this);
        if (returnVal == JFileChooser.APPROVE_OPTION) {
            String fileName = fileChooser.getSelectedFile().getName();
            String ext = BEFileUtils.getFileExtention(fileName);
            File outputFile;
            if (ext.equals("csv")) {
                outputFile = new File(fileChooser.getSelectedFile().getAbsolutePath());
            } else {
                outputFile = new File(fileChooser.getSelectedFile() + ".csv");
            }
            if (outputFile.exists()) {
                int userResponse = DialogCreator.deleteExistFileDialog(this);
                if (userResponse != 0) {
                    return;
                }
            }
            BLFileExporter exporter = new BLFileExporter();
            boolean succeeded = exporter.exportFilteredTableToCSV(outputFile, selectedNodeData);
            if (succeeded) {
                DialogCreator.showMessage(this, "Export Completed", "Export was completed successfully.", JOptionPane.INFORMATION_MESSAGE);
            } else {
                DialogCreator.showMessage(this, "Export Failed", "Export failed.\nInformation can be found in 'runtime.log' file.", JOptionPane.ERROR_MESSAGE);
            }
        }
    }

    void exportToXML(TreePath path) {

        DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode) path.getLastPathComponent();
        NodeData selectedNodeData = (NodeData) treeNode.getUserObject();

        File workspaceDir = new File(FilesConfig.WORKSPACE_DIR_PATH);
        JFileChooser fileChooser;
        if(workspaceDir.isDirectory()){
            fileChooser = new JFileChooser(workspaceDir);
        }
        else {
            fileChooser = new JFileChooser(System.getProperty("user.home"));
        }
        
        int returnVal = fileChooser.showSaveDialog(this);
        if (returnVal == JFileChooser.APPROVE_OPTION) {
            String fileName = fileChooser.getSelectedFile().getName();
            String ext = BEFileUtils.getFileExtention(fileName);
            File outputFile;
            if (ext.equals("xml")) {
                outputFile = new File(fileChooser.getSelectedFile().getAbsolutePath());
            } else {
                outputFile = new File(fileChooser.getSelectedFile() + ".xml");
            }
            if (outputFile.exists()) {
                int userResponse = DialogCreator.deleteExistFileDialog(this);
                if (userResponse != 0) {
                    return;
                }
            }
            BLFileExporter exporter = new BLFileExporter();
            boolean succeeded = exporter.exportFilteredTableToXML(outputFile, selectedNodeData);
            if (succeeded) {
                DialogCreator.showMessage(this, "Export Completed", "Export was completed successfully.", JOptionPane.INFORMATION_MESSAGE);
            } else {
                DialogCreator.showMessage(this, "Export Failed", "Export failed.\nInformation can be found in 'runtime.log' file.", JOptionPane.ERROR_MESSAGE);
            }
        }
    }

    void expandAll(TreePath parent, boolean expand) {
        // Traverse children
        TreeNode node = (TreeNode) parent.getLastPathComponent();
        if (node.getChildCount() > 0) {
            for (Enumeration e = node.children(); e.hasMoreElements();) {
                TreeNode n = (TreeNode) e.nextElement();
                TreePath path = parent.pathByAddingChild(n);
                expandAll(path, expand);
            }
        }

        // Expansion or collapse must be done bottom-up
        if (expand) {
            tree.expandPath(parent);
        } else {
            tree.collapsePath(parent);
        }
    }

    private void initWindowListner() {
        this.addWindowListener(new WindowAdapter() {

            @Override
            public void windowClosed(WindowEvent e) {
                if (closeConnectionOnClose) {
                    BLConnetionManager.closeConnection();
                }
            }

            @Override
            public void windowClosing(WindowEvent e) {
                if (userClickOnExit) {
                    if (DialogCreator.closeProgramDialogSaveWarn((JFrame) e.getSource()) == 0) {
                        setVisible(false);
                        BLConnetionManager.closeConnection();
                        dispose();
                    }
                } else if (closeConnectionOnClose) {
                    BLConnetionManager.closeConnection();
                }
            }
        });
    }

    void editFilter(TreePath path) {
        DefaultMutableTreeNode originalNode = (DefaultMutableTreeNode)path.getLastPathComponent();
        NodeData originalNodeData = (NodeData)originalNode.getUserObject();
        
        if (originalNodeData.isRootFilter()) {
            return;
        }
        
        String previousWhere = originalNodeData.getPreviousFilters();
        String currentFilter = originalNodeData.getCurrentFilter();
        AddFilterDialog dialog = new AddFilterDialog(this, this.columnsDataConatiner, previousWhere,currentFilter);
        dialog.setVisible(true);
        String filter = dialog.getWhere();
        
        if (filter != null && !filter.equals("")) {
            DefaultMutableTreeNode parentNode = (DefaultMutableTreeNode)originalNode.getParent();
            NodeData parentNodeData = (NodeData)parentNode.getUserObject();
            DefaultMutableTreeNode newNode = new DefaultMutableTreeNode(new NodeData(filter, parentNodeData));

            List<DefaultMutableTreeNode> childrenList = new ArrayList<>();
            for (Enumeration e = originalNode.children(); e.hasMoreElements();) {
                childrenList.add((DefaultMutableTreeNode)e.nextElement());
            }
            
            for (DefaultMutableTreeNode child : childrenList) {
                newNode.add(child);
            }
            
            for (Enumeration e = newNode.children(); e.hasMoreElements();) {
                updateChildFilter((DefaultMutableTreeNode)e.nextElement(),newNode);
            }
            
            int index = parentNode.getIndex(originalNode);
            parentNode.remove(originalNode);
            parentNode.insert(newNode, index);
            DefaultTreeModel model = (DefaultTreeModel)tree.getModel();
            model.reload(newNode);
            
            tree.setSelectionPath(new TreePath( newNode.getPath()));
            tree.setSelectionPath( new TreePath( ((DefaultTreeModel)tree.getModel()).getPathToRoot(newNode)));
        }
    }

    private void updateChildFilter(DefaultMutableTreeNode child, DefaultMutableTreeNode parent) {
        assert parent != null;
        if(child == null) return;
        NodeData parentData = (NodeData)parent.getUserObject();
        NodeData oldChildData = (NodeData)(child.getUserObject());
        String childFilter = oldChildData.getCurrentFilter();
        NodeData newChildData = new NodeData(childFilter,parentData);
        child.setUserObject(newChildData);
        
        for(Enumeration e = child.children(); e.hasMoreElements();){
            updateChildFilter((DefaultMutableTreeNode)e.nextElement(), child);
        }
    }
}
